﻿namespace com.game.sound
{
    using com.game.manager;
    using com.game.preloader;
    using com.game.utils;
    using com.u3d.bases.debug;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;
    using UnityEngine;

    public class SoundMgr : IPreloader
    {
        private IDictionary<string, AudioClip> clipDictionary = new Dictionary<string, AudioClip>();
        private IDictionary<string, AudioSetting> clipSettingDictionary = new Dictionary<string, AudioSetting>();
        private float effectVolumn = 1f;
        public static SoundMgr Instance = ((Instance != null) ? Instance : new SoundMgr());
        private bool mute;
        private IList<string> preladAudioNameList = new List<string>();
        private int preloadIndex;
        private IList<SysReadyLoadVo> preLoadList;
        private float sceneVolumn = 0.4f;
        private IList<SoundPlayer> soundList = new List<SoundPlayer>();

        private SoundMgr()
        {
        }

        private void FreeUnusedAudio()
        {
            IList<string> list = new List<string>();
            IEnumerator<KeyValuePair<string, AudioClip>> enumerator = this.clipDictionary.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    KeyValuePair<string, AudioClip> current = enumerator.Current;
                    if (!this.preladAudioNameList.Contains(current.Key))
                    {
                        list.Add(current.Key);
                    }
                }
            }
            finally
            {
                if (enumerator == null)
                {
                }
                enumerator.Dispose();
            }
            IEnumerator<string> enumerator2 = list.GetEnumerator();
            try
            {
                while (enumerator2.MoveNext())
                {
                    string key = enumerator2.Current;
                    this.clipDictionary.Remove(key);
                }
            }
            finally
            {
                if (enumerator2 == null)
                {
                }
                enumerator2.Dispose();
            }
        }

        private string GetSceneSoundAssetPath(string soundId)
        {
            return ("Music/Scene/" + soundId + ".assetbundle");
        }

        private string GetSkillSoundAssetPath(string soundId)
        {
            return ("Music/Skill/" + soundId + ".assetbundle");
        }

        private string GetSpeechSoundAssetPath(string soundId, string roleType)
        {
            string[] textArray1 = new string[] { "Music/Speech/", roleType, "/", soundId, ".assetbundle" };
            return string.Concat(textArray1);
        }

        private string GetUISoundAssetPath(string soundId)
        {
            return ("Music/UI/" + soundId + ".assetbundle");
        }

        private SoundPlayer GetUnusedPlayer()
        {
            IEnumerator<SoundPlayer> enumerator = this.soundList.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    SoundPlayer current = enumerator.Current;
                    if (!current.IsPlaying)
                    {
                        return current;
                    }
                }
            }
            finally
            {
                if (enumerator == null)
                {
                }
                enumerator.Dispose();
            }
            return null;
        }

        public bool IsPlaying(string soundId)
        {
            if (this.clipSettingDictionary.ContainsKey(soundId) && this.clipSettingDictionary[soundId].IsLoading)
            {
                return true;
            }
            if (this.clipDictionary.ContainsKey(soundId))
            {
                AudioClip clip = this.clipDictionary[soundId];
                IEnumerator<SoundPlayer> enumerator = this.soundList.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        SoundPlayer current = enumerator.Current;
                        if ((clip == current.Clip) && current.IsPlaying)
                        {
                            return true;
                        }
                    }
                }
                finally
                {
                    if (enumerator == null)
                    {
                    }
                    enumerator.Dispose();
                }
            }
            return false;
        }

        private void PlayAfterLoad(AudioClip clip)
        {
            if (null != clip)
            {
                string name = clip.name;
                if (!this.clipDictionary.ContainsKey(name))
                {
                    this.clipDictionary.Add(name, clip);
                }
                SoundPlayer unusedPlayer = this.GetUnusedPlayer();
                if (unusedPlayer == null)
                {
                    unusedPlayer = new SoundPlayer(clip);
                    this.soundList.Add(unusedPlayer);
                }
                else
                {
                    unusedPlayer.Clip = clip;
                }
                AudioSetting setting = this.clipSettingDictionary[name];
                setting.IsLoading = false;
                unusedPlayer.Loop = setting.Loop;
                unusedPlayer.Volumn = setting.Volumn;
                unusedPlayer.Delay = setting.Delay;
                unusedPlayer.Mute = this.mute;
                unusedPlayer.Play();
            }
        }

        private void PlayClip(string soundId, string assetBundleName, bool loop, float volumn, float delay = 0f)
        {
            try
            {
                if (!StringUtils.isEmpty(soundId))
                {
                    AudioSetting setting = new AudioSetting {
                        Loop = loop,
                        Volumn = volumn,
                        Delay = delay,
                        IsLoading = true
                    };
                    this.clipSettingDictionary[soundId] = setting;
                    if (!this.clipDictionary.ContainsKey(soundId))
                    {
                        AssetManager.Instance.LoadAsset<AudioClip>(assetBundleName, new LoadAssetFinish<AudioClip>(this.PlayAfterLoad), soundId, false, true);
                    }
                    else
                    {
                        this.PlayAfterLoad(this.clipDictionary[soundId]);
                    }
                }
            }
            catch (Exception exception)
            {
                com.u3d.bases.debug.Log.warin(this, exception.StackTrace);
            }
        }

        public void PlaySceneAudio(string soundId)
        {
            string sceneSoundAssetPath = this.GetSceneSoundAssetPath(soundId);
            this.PlayClip(soundId, sceneSoundAssetPath, true, this.sceneVolumn, 0f);
        }

        public void PlaySkillAudio(string soundId, float delay = 0f)
        {
            string skillSoundAssetPath = this.GetSkillSoundAssetPath(soundId);
            this.PlayClip(soundId, skillSoundAssetPath, false, this.effectVolumn, delay);
        }

        public void PlaySpeechAudio(string soundId, string roleType, float delay = 0f)
        {
            string speechSoundAssetPath = this.GetSpeechSoundAssetPath(soundId, roleType);
            this.PlayClip(soundId, speechSoundAssetPath, false, this.effectVolumn, delay);
        }

        public void PlayUIAudio(string soundId, float delay = 0f)
        {
            string uISoundAssetPath = this.GetUISoundAssetPath(soundId);
            this.PlayClip(soundId, uISoundAssetPath, false, this.effectVolumn, delay);
        }

        private void PreloadResource()
        {
            try
            {
                while (this.preloadIndex < this.preLoadList.Count)
                {
                    string subid = this.preLoadList[this.preloadIndex].subid;
                    string skillSoundAssetPath = this.GetSkillSoundAssetPath(this.preLoadList[this.preloadIndex].subid);
                    if (!this.clipDictionary.ContainsKey(subid))
                    {
                        this.preladAudioNameList.Add(subid);
                        AssetManager.Instance.LoadAsset<AudioClip>(skillSoundAssetPath, new LoadAssetFinish<AudioClip>(this.SoundPreLoaded), null, false, true);
                        return;
                    }
                    this.preloadIndex++;
                }
            }
            catch (Exception exception)
            {
                com.u3d.bases.debug.Log.warin(this, "preloadResource error, exception is: " + exception.Message);
            }
        }

        [DebuggerHidden]
        public IEnumerator PreloadResourceList(IList<SysReadyLoadVo> preLoadList)
        {
            return new <PreloadResourceList>c__Iterator3F { preLoadList = preLoadList, <$>preLoadList = preLoadList, <>f__this = this };
        }

        public void PreloadSceneAudio(string soundId)
        {
            if (!this.clipDictionary.ContainsKey(soundId))
            {
                string sceneSoundAssetPath = this.GetSceneSoundAssetPath(soundId);
                AssetManager.Instance.LoadAsset<AudioClip>(sceneSoundAssetPath, new LoadAssetFinish<AudioClip>(this.SceneSoundPreLoaded), null, false, true);
            }
        }

        private void SceneSoundPreLoaded(AudioClip clip)
        {
            if ((null != clip) && !this.clipDictionary.ContainsKey(clip.name))
            {
                this.clipDictionary.Add(clip.name, clip);
            }
        }

        private void SoundPreLoaded(AudioClip clip)
        {
            try
            {
                if ((null != clip) && !this.clipDictionary.ContainsKey(clip.name))
                {
                    this.clipDictionary.Add(clip.name, clip);
                }
            }
            finally
            {
                this.preloadIndex++;
                this.PreloadResource();
            }
        }

        public void Stop(string soundId)
        {
            AudioClip clip = this.clipDictionary[soundId];
            if (null != clip)
            {
                IEnumerator<SoundPlayer> enumerator = this.soundList.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        SoundPlayer current = enumerator.Current;
                        if ((clip == current.Clip) && current.IsPlaying)
                        {
                            current.Stop();
                            return;
                        }
                    }
                }
                finally
                {
                    if (enumerator == null)
                    {
                    }
                    enumerator.Dispose();
                }
            }
        }

        public void StopAll()
        {
            IEnumerator<SoundPlayer> enumerator = this.soundList.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    SoundPlayer current = enumerator.Current;
                    if (current.IsPlaying)
                    {
                        current.Stop();
                    }
                }
            }
            finally
            {
                if (enumerator == null)
                {
                }
                enumerator.Dispose();
            }
            this.FreeUnusedAudio();
        }

        public float EffectVolumn
        {
            get
            {
                return this.effectVolumn;
            }
            set
            {
                this.effectVolumn = Mathf.Clamp01(value);
                IEnumerator<SoundPlayer> enumerator = this.soundList.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        SoundPlayer current = enumerator.Current;
                        if (!current.Loop)
                        {
                            current.Volumn = value;
                        }
                    }
                }
                finally
                {
                    if (enumerator == null)
                    {
                    }
                    enumerator.Dispose();
                }
            }
        }

        public bool Mute
        {
            get
            {
                return this.mute;
            }
            set
            {
                if (this.mute != value)
                {
                    this.mute = value;
                    IEnumerator<SoundPlayer> enumerator = this.soundList.GetEnumerator();
                    try
                    {
                        while (enumerator.MoveNext())
                        {
                            SoundPlayer current = enumerator.Current;
                            current.Mute = value;
                        }
                    }
                    finally
                    {
                        if (enumerator == null)
                        {
                        }
                        enumerator.Dispose();
                    }
                }
            }
        }

        public float SceneVolumn
        {
            get
            {
                return this.sceneVolumn;
            }
            set
            {
                this.sceneVolumn = Mathf.Clamp01(value);
                IEnumerator<SoundPlayer> enumerator = this.soundList.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        SoundPlayer current = enumerator.Current;
                        if (current.Loop)
                        {
                            current.Volumn = value;
                        }
                    }
                }
                finally
                {
                    if (enumerator == null)
                    {
                    }
                    enumerator.Dispose();
                }
            }
        }

        [CompilerGenerated]
        private sealed class <PreloadResourceList>c__Iterator3F : IEnumerator, IDisposable, IEnumerator<object>
        {
            internal object $current;
            internal int $PC;
            internal IList<SysReadyLoadVo> <$>preLoadList;
            internal SoundMgr <>f__this;
            internal IList<SysReadyLoadVo> preLoadList;

            [DebuggerHidden]
            public void Dispose()
            {
                this.$PC = -1;
            }

            public bool MoveNext()
            {
                uint num = (uint) this.$PC;
                this.$PC = -1;
                switch (num)
                {
                    case 0:
                        this.<>f__this.preLoadList = this.preLoadList;
                        this.<>f__this.preloadIndex = 0;
                        this.<>f__this.PreloadResource();
                        break;

                    case 1:
                        break;

                    default:
                        goto Label_008D;
                }
                if (this.<>f__this.preloadIndex < this.<>f__this.preLoadList.Count)
                {
                    this.$current = 0;
                    this.$PC = 1;
                    return true;
                }
                this.$PC = -1;
            Label_008D:
                return false;
            }

            [DebuggerHidden]
            public void Reset()
            {
                throw new NotSupportedException();
            }

            object IEnumerator<object>.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.$current;
                }
            }

            object IEnumerator.Current
            {
                [DebuggerHidden]
                get
                {
                    return this.$current;
                }
            }
        }
    }
}

